<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1 class="ap" id="hh">{{msg}}</h1>
    </div>
</body>

</html>
<script src='https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js'></script>
<script>
    // vue2 router 7 + 组件:8 + 缓存的:2 +自定义指令:3
    // vue3 自定义指令:7 组件 11 缓存 2 + 路由7 
    // react 9个
    // 小程序6

    //虚拟dom:使用js的api,模拟真实dom树的嵌套结构,创建对应的节点

    // let div = document.createElement("div");
    // div.id = 'app'
    // let h1 = document.createElement("h1");
    // h1.className = 'ap'
    // h1.innerText = '{{msg}}'
    // div.appendChild(h1)


    //1.vue需要获取模板

    //2.获取模板之后 进行编译 将获取到的模板 在内存中编译成虚拟dom

    //3.对虚拟dom进行 指令解析 插值解析 动态属性解析 .... 一系列操作

    //4.编译完成因为在内存中,最后需要替换原来的模板,展示到页面上

    //为什么要使用虚拟dom? 为了实现页面的高效更新

    //虚拟dom性能一定比操作真实dom好嘛? 不是 

    //场景:如果说 页面结构非常简单 比如只有一个节点 如果要实现更新 直接获取节点 然后重新设置innerText就可以了

    //虚拟dom是针对较为复杂的页面结构 对特定的节点更新 才能发挥最大的性能优势

    //关于生命周期的问题

    //1.讲一下钩子函数

    //2.描述一下在哪些阶段执行 虚拟dom是否创建 数据是否劫持 虚拟dom是否挂载

    //3.异步请求在哪里发送 

    //4.destroyed 这些钩子函数你在项目中的应用

    //5.父子嵌套的时候,钩子函数执行顺序

    //6.哪个钩子能操作dom

    let vm = new Vue({
        el: "#app",
        data: {
            msg: "maby we just slow down"
        },
        //创建之前,这里面做数据初始化
        beforeCreate() {
            // 这个钩子里面 data methods 尚未被注入 虚拟dom也没有被创建
            // 能不能发送异步请求 能不能修改dom
            //1.不能发送异步请求
            //2.不能操作dom
            console.group('beforeCreate')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerText)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //创建之后 数据初始化完成
        created() {
            //能不能修改data 发送异步请求? 可以
            // this.msg = '7777'
            //能不能操作dom 不能

            console.group('created')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerHTML)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //虚拟dom挂载之前
        beforeMount() {
            //虚拟dom已经创建
            //依旧不能操作dom
            console.group('beforeMount')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerHTML)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //虚拟dom挂载之后
        mounted() {
            //虚拟dom已经创建,并且对数据都已经解析完毕,替换了页面原来的模板
            //使用频率最高的钩子函数
            console.group('mounted')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerHTML)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //更新之前
        beforeUpdate() {
            console.group('beforeUpdate')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerHTML)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //更新之后
        updated() {
            console.group('updated')
            console.log('data', this.$data)
            console.log('h1的内容', document.getElementById('hh').innerHTML)
            console.log('虚拟dom', this.$el)
            console.groupEnd()
        },
        //销毁前
        // 什么时候会触发组件的销毁?
        //1.主动调用$destroy()
        //2.v-if 
        //3.动态组件
        //4.路由
        beforeDestroy() {
            //一个技巧就是 这两个钩子用一个就行了 componentWillUnMount
            //这里一般写什么业务?
            //我的项目中一般会在这个钩子函数中 卸载定时器 卸载持续一些持续性事件监听 
            //之前我网易云音乐的时候 有audio标签 有个持续性监听进度条的事件 如果组件卸载掉 没有把事件移除就会报错
            console.log('即将蹦沙卡拉卡')
        },
        //销毁后
        destroyed() {
            console.log('蹦沙卡拉卡')
        },
        // render(createElement) { //创建虚拟dom的方法
        //     let VNode = createElement("div", { attrs: { id: "app" } }, [
        //         createElement("h1", { class: { ap: true } }, "{{msg123}}")
        //     ])
        //     console.log(VNode)
        //     return VNode
        // }
    })
</script>